package com.funsport.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.funsport.entity.PointOrder;
import com.funsport.entity.PointProduct;
import com.funsport.entity.User;
import com.funsport.mapper.PointOrderMapper;
import com.funsport.service.IPointOrderService;
import com.funsport.service.IPointProductService;
import com.funsport.service.IUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Random;

/**
 * 积分订单服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PointOrderServiceImpl extends ServiceImpl<PointOrderMapper, PointOrder> implements IPointOrderService {
    
    private final IPointProductService pointProductService;
    private final IUserService userService;
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public String exchange(Long userId, Long productId, Integer quantity, String receiverName, String receiverPhone, String receiverAddress) {
        // 1. 检查商品
        PointProduct product = pointProductService.getById(productId);
        if (product == null) {
            throw new RuntimeException("商品不存在");
        }
        
        if (!"active".equals(product.getStatus())) {
            throw new RuntimeException("商品已下架");
        }
        
        if (product.getStock() < quantity) {
            throw new RuntimeException("库存不足");
        }
        
        // 2. 检查用户积分
        User user = userService.getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        int totalPoints = product.getPointsRequired() * quantity;
        if (user.getPoints() < totalPoints) {
            throw new RuntimeException("积分不足");
        }
        
        // 3. 扣除积分
        user.setPoints(user.getPoints() - totalPoints);
        userService.updateById(user);
        
        // 4. 减少库存
        pointProductService.decreaseStock(productId, quantity);
        
        // 5. 创建订单
        String orderNo = generateOrderNo();
        
        PointOrder order = new PointOrder();
        order.setOrderNo(orderNo);
        order.setUserId(userId);
        order.setProductId(productId);
        order.setProductName(product.getName());
        order.setProductImage(product.getImage());
        order.setPointsCost(totalPoints);
        order.setQuantity(quantity);
        order.setReceiverName(receiverName);
        order.setReceiverPhone(receiverPhone);
        order.setReceiverAddress(receiverAddress);
        order.setStatus("pending");
        
        this.save(order);
        
        log.info("积分兑换成功: 订单号={}, 用户ID={}, 商品ID={}, 数量={}, 消耗积分={}", 
            orderNo, userId, productId, quantity, totalPoints);
        
        return orderNo;
    }
    
    @Override
    public Page<PointOrder> getUserOrders(Long userId, Integer page, Integer pageSize, String status) {
        LambdaQueryWrapper<PointOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PointOrder::getUserId, userId);
        
        if (status != null && !status.isEmpty()) {
            wrapper.eq(PointOrder::getStatus, status);
        }
        
        wrapper.orderByDesc(PointOrder::getCreatedAt);
        
        return this.page(new Page<>(page, pageSize), wrapper);
    }
    
    @Override
    public Page<PointOrder> getAllOrders(Integer page, Integer pageSize, String status, Long userId) {
        LambdaQueryWrapper<PointOrder> wrapper = new LambdaQueryWrapper<>();
        
        if (status != null && !status.isEmpty()) {
            wrapper.eq(PointOrder::getStatus, status);
        }
        
        if (userId != null) {
            wrapper.eq(PointOrder::getUserId, userId);
        }
        
        wrapper.orderByDesc(PointOrder::getCreatedAt);
        
        return this.page(new Page<>(page, pageSize), wrapper);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void ship(String orderNo, String shippingNo) {
        PointOrder order = getByOrderNo(orderNo);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        if (!"pending".equals(order.getStatus()) && !"processing".equals(order.getStatus())) {
            throw new RuntimeException("订单状态不允许发货");
        }
        
        order.setStatus("shipped");
        order.setShippingNo(shippingNo);
        order.setShippedAt(LocalDateTime.now());
        
        this.updateById(order);
        log.info("订单已发货: {}, 物流单号: {}", orderNo, shippingNo);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void complete(String orderNo) {
        PointOrder order = getByOrderNo(orderNo);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        if (!"shipped".equals(order.getStatus())) {
            throw new RuntimeException("订单未发货，无法完成");
        }
        
        order.setStatus("completed");
        order.setCompletedAt(LocalDateTime.now());
        
        this.updateById(order);
        log.info("订单已完成: {}", orderNo);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancel(String orderNo, Long userId) {
        PointOrder order = getByOrderNo(orderNo);
        if (order == null) {
            throw new RuntimeException("订单不存在");
        }
        
        if (!order.getUserId().equals(userId)) {
            throw new RuntimeException("无权操作此订单");
        }
        
        if (!"pending".equals(order.getStatus())) {
            throw new RuntimeException("订单状态不允许取消");
        }
        
        // 退还积分
        User user = userService.getById(userId);
        user.setPoints(user.getPoints() + order.getPointsCost());
        userService.updateById(user);
        
        // 恢复库存
        pointProductService.increaseStock(order.getProductId(), order.getQuantity());
        
        // 更新订单状态
        order.setStatus("cancelled");
        this.updateById(order);
        
        log.info("订单已取消: {}, 退还积分: {}", orderNo, order.getPointsCost());
    }
    
    /**
     * 根据订单号获取订单
     */
    private PointOrder getByOrderNo(String orderNo) {
        LambdaQueryWrapper<PointOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PointOrder::getOrderNo, orderNo);
        return this.getOne(wrapper);
    }
    
    /**
     * 生成订单号
     */
    private String generateOrderNo() {
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
        String timestamp = LocalDateTime.now().format(formatter);
        String random = String.format("%06d", new Random().nextInt(1000000));
        return "POINT" + timestamp + random;
    }
}

